import {
  createContext,
  memo,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from 'react';
import type { FC, PropsWithChildren } from 'react';
import { Button, Dropdown, Menu, message, Modal } from 'antd';
import {
  resChangeAddress,
  resChangeAddressDefault,
  resDeleteAddress,
} from '@/services/address';
import { resAddAddress, resAddressList } from '@/services/address';
import { EllipsisOutlined } from '@ant-design/icons';
import { useRequest } from 'ahooks';
import classNames from 'classnames';
import { isNumber } from 'lodash';
import QueueAnim from 'rc-queue-anim';
import AddressFormModal from '@/components/AddressFormModal';
import './index.scss';

const formatAddressParam = (value: any) => {
  if (value.city && Array.isArray(value.city)) {
    return {
      name: value.name,
      address: value.address,
      phone: value.phone,
      is_default: value.is_default ? 1 : 0,
      province: value.city[0],
      city: value.city[1],
      county: value.city[2],
    } as API.AddressParams;
  }
  return {
    name: value.name,
    address: value.address,
    phone: value.phone,
    is_default: value.is_default ? 1 : 0,
    province: value.city,
  } as API.AddressParams;
};

interface AddressCardContextParam {
  run: Function;
  onClickOpen: (status: ModalStatus, defaultValue?: API.AddressStruct) => void;
}

type ModalStatus = 'edit' | 'add';

const AddressCardContext = createContext<AddressCardContextParam>(
  {} as AddressCardContextParam
);

const AddressCard: FC<
  PropsWithChildren<{
    data: API.AddressStruct[];
    onChange: (id: number) => void;
    checkedValue: number | number[];
    run: Function;
  }>
> = ({ data, onChange, checkedValue, run }) => {
  const onClick = useCallback(
    (id: number) => {
      onChange(id);
    },
    [data]
  );
  const [openModal, setOpenModal] = useState(false);

  const [modalStatus, setModalStatus] = useState<ModalStatus>('add');
  const [defaultAddress, setDefaultAddress] = useState<API.AddressStruct>();

  const { runAsync } = useRequest(resAddAddress, { manual: true });
  const { runAsync: changeAddress } = useRequest(resChangeAddress, {
    manual: true,
  });

  const onOk = useCallback(() => {
    setOpenModal(false);
  }, []);

  const onCancel = useCallback(() => {
    setOpenModal(false);
  }, []);

  const onClickOpen = useCallback(
    (status: ModalStatus, defaultValue?: API.AddressStruct) => {
      setModalStatus(status);
      setDefaultAddress(defaultValue);
      setOpenModal(true);
    },
    []
  );

  const onFinish = useCallback(
    (value: any) => {
      switch (modalStatus) {
        case 'add':
          runAsync(formatAddressParam(value)!).then(() => {
            message.success('添加地址成功');
            run();
            setOpenModal(false);
          });
          break;
        case 'edit':
          if (defaultAddress && isNumber(defaultAddress.id)) {
            changeAddress(defaultAddress.id, formatAddressParam(value)!).then(
              () => {
                message.success('修改地址成功');
                run();
                setOpenModal(false);
                setDefaultAddress(undefined);
              }
            );
          } else {
            console.log(defaultAddress);
            message.warn('地址id错误');
          }
          break;
      }
    },
    [modalStatus, defaultAddress]
  );

  const contextValue = useMemo(() => {
    return { run, onClickOpen };
  }, [run, onClickOpen]);
  return (
    <AddressCardContext.Provider value={contextValue}>
      <div className={'relative'}>
        <div className={'absolute right-2 -top-[40px]'}>
          <Button
            type={'link'}
            onClick={() => {
              onClickOpen('add');
            }}
          >
            添加新地址
          </Button>
        </div>
        <QueueAnim
          type={['right', 'bottom']}
          component={'ul'}
          appear={false}
          className={
            'grid grid-cols-3 xl:grid-cols-4 gap-y-3  place-content-center place-items-start'
          }
        >
          {data.length > 0
            ? data.map((value) => (
                <li key={value.id}>
                  <AddressCardItem
                    onClick={onClick}
                    data={value}
                    checked={
                      checkedValue === value.id ||
                      (Array.isArray(checkedValue) &&
                        checkedValue.includes(value.id))
                    }
                  />
                </li>
              ))
            : null}
        </QueueAnim>
        <AddressFormModal
          isModalOpen={openModal}
          onOk={onOk}
          onCancel={onCancel}
          onFinish={onFinish}
          defaultValue={modalStatus === 'edit' ? defaultAddress : undefined}
        />
      </div>
    </AddressCardContext.Provider>
  );
};

const AddressCardTool: FC<PropsWithChildren<{ data: API.AddressStruct }>> = ({
  data,
}) => {
  const context = useContext(AddressCardContext);
  const menu = (
    <Menu
      items={[
        {
          key: 'edit',
          label: <span className={'text-xs text-center'}>修改</span>,
          onClick: () => {
            context.onClickOpen('edit', data);
          },
        },
        {
          key: 'delete',
          label: <span className={'text-xs text-center'}>删除</span>,
          onClick: () => {
            Modal.confirm({
              title: '删除地址',
              content: '确认要删除当前地址吗？',
              okText: '确定',
              okType: 'danger',
              cancelText: '取消',
              onOk() {
                resDeleteAddress(data.id).then(() => {
                  message.success('删除成功');
                  context.run();
                });
              },
            });
          },
        },
        {
          key: 'default',
          label: <span className={'text-xs text-center'}>设为默认</span>,
          onClick: () => {
            resChangeAddressDefault(data.id).then(() => {
              context.run();
            });
          },
        },
      ]}
    />
  );
  return (
    <Dropdown overlay={menu} trigger={['click']} placement="bottom">
      <EllipsisOutlined />
    </Dropdown>
  );
};

const AddressCardItem: FC<
  PropsWithChildren<{
    data: API.AddressStruct;
    checked: boolean;
    onClick: (id: number) => void;
  }>
> = ({ data, checked, onClick }) => {
  return (
    <div
      className={classNames(
        'py-2 px-4 relative transition border bg-gray-50 hover:border-blue-600 w-[250px] min-h-[104px] rounded-lg cursor-pointer',
        { 'address-card-checked': checked }
      )}
      onClick={() => {
        onClick(data.id);
      }}
    >
      <div className={'flex items-center py-1.5 text-base text-black'}>
        <div className={'space-x-1'}>
          <span>{data.province}</span>
          <span>{data.city}</span>
          <span>
            (<span className={'px-1'}>{data.name}</span>收)
          </span>
        </div>
        <div
          className={'absolute right-0 top-0 px-2'}
          onClick={(e) => {
            e.stopPropagation();
          }}
        >
          <AddressCardTool data={data} />
        </div>
        <div
          className={classNames(
            'absolute right-0 bottom-0 rounded text-xs px-1  border bg-gray-100/50 border-green-500 ',
            { hidden: !data.is_default }
          )}
        >
          默认地址
        </div>
      </div>
      <div className={' leading-6'}>
        <span>{data.county}</span>
        <span className={'mx-1'}>{data.address}</span>
        <span>{data.phone.slice(3)}</span>
      </div>
    </div>
  );
};

export default memo(AddressCard);
